package translated;

import java.util.*;
import edu.pku.sei.modeler.model.core.*;
import edu.pku.sei.modeler.jet.util.*;
import edu.pku.sei.modeler.model.common.MetaTypedList;

public class ModelGen
{
  protected static String nl;
  public static synchronized ModelGen create(String lineSeparator)
  {
    nl = lineSeparator;
    ModelGen result = new ModelGen();
    nl = null;
    return result;
  }

  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
  protected final String TEXT_1 = "/**" + NL + " * Copyright (c) Software Institude of PKU" + NL + " * All rights reserved. " + NL + " * This program and the accompanying materials" + NL + " * are made available under the terms of the Eclipse Public License v1.0" + NL + " * which accompanies this distribution, and is available at" + NL + " * http://www.eclipse.org/legal/epl-v10.html" + NL + " *" + NL + " */" + NL + "package ";
  protected final String TEXT_2 = ";" + NL + "// imports:" + NL + "import org.w3c.dom.Element;" + NL + "" + NL + "import edu.pku.sei.gefcommon.descriptor.annotation.MethodProperty;" + NL + "import edu.pku.sei.modeler.model.common.*;" + NL + "import edu.pku.sei.modeler.model.core.*;" + NL + "import edu.pku.sei.modeler.model.xml.XMLUtility;" + NL + "import ";
  protected final String TEXT_3 = ";" + NL;
  protected final String TEXT_4 = NL + "import ";
  protected final String TEXT_5 = ";";
  protected final String TEXT_6 = NL;
  protected final String TEXT_7 = NL + "import ";
  protected final String TEXT_8 = ".";
  protected final String TEXT_9 = ";";
  protected final String TEXT_10 = NL + NL + "/**" + NL + " * @generated" + NL + " *" + NL + " */" + NL + "public ";
  protected final String TEXT_11 = "class ";
  protected final String TEXT_12 = " extends ";
  protected final String TEXT_13 = " implements ";
  protected final String TEXT_14 = " {" + NL + "\t// attributes" + NL + "\t";
  protected final String TEXT_15 = NL + "\t";
  protected final String TEXT_16 = " ";
  protected final String TEXT_17 = " ";
  protected final String TEXT_18 = ";" + NL + "\t";
  protected final String TEXT_19 = NL + "\t" + NL + "\t";
  protected final String TEXT_20 = NL + "\tprotected ";
  protected final String TEXT_21 = " ";
  protected final String TEXT_22 = ";" + NL + "\t";
  protected final String TEXT_23 = NL + "\t" + NL + "\t// references" + NL + "\t";
  protected final String TEXT_24 = NL + "\tprotected MetaTypedList ";
  protected final String TEXT_25 = ";" + NL + "\t";
  protected final String TEXT_26 = NL + "\t" + NL + "\t";
  protected final String TEXT_27 = NL + "\tprotected MetaTypedList ";
  protected final String TEXT_28 = ";" + NL + "\t";
  protected final String TEXT_29 = NL + "\t// getters & setters for attributes" + NL + "\t";
  protected final String TEXT_30 = NL + "\t@MethodProperty(" + NL + "\t\t\tid = \"";
  protected final String TEXT_31 = "_";
  protected final String TEXT_32 = "\"," + NL + "\t\t\tcatalog = \"Model\"," + NL + "\t\t\tname = ";
  protected final String TEXT_33 = "," + NL + "\t\t\tsetter = \"set";
  protected final String TEXT_34 = "\"" + NL + "\t\t\t)" + NL + "\t";
  protected final String TEXT_35 = NL + "\tpublic ";
  protected final String TEXT_36 = " get";
  protected final String TEXT_37 = "() {" + NL + "\t\treturn ";
  protected final String TEXT_38 = ";" + NL + "\t}" + NL + "\tpublic void set";
  protected final String TEXT_39 = "(";
  protected final String TEXT_40 = " new";
  protected final String TEXT_41 = ") {" + NL + "\t\t";
  protected final String TEXT_42 = " old";
  protected final String TEXT_43 = " = ";
  protected final String TEXT_44 = ";" + NL + "\t\t";
  protected final String TEXT_45 = " = new";
  protected final String TEXT_46 = ";" + NL + "\t\tfirePropertyChange(";
  protected final String TEXT_47 = ", old";
  protected final String TEXT_48 = ", new";
  protected final String TEXT_49 = ");" + NL + "\t}" + NL + "\t";
  protected final String TEXT_50 = NL + "\t// getters for references" + NL + "\t";
  protected final String TEXT_51 = NL + "\tpublic MetaTypedList get";
  protected final String TEXT_52 = "() {" + NL + "\t\tif(";
  protected final String TEXT_53 = " == null) {" + NL + "\t\t\t";
  protected final String TEXT_54 = " = new MetaTypedList(";
  protected final String TEXT_55 = ".class, this, ";
  protected final String TEXT_56 = ");" + NL + "\t\t}" + NL + "\t\treturn ";
  protected final String TEXT_57 = ";" + NL + "\t}" + NL + "\t";
  protected final String TEXT_58 = NL + "\t// save & load" + NL + "\tpublic void serialize(Element root) {" + NL + "\t\tsuper.serialize(root);" + NL + "\t\t// attributes" + NL + "\t\t";
  protected final String TEXT_59 = NL + "\t\tXMLUtility.xmlInstance.serializeAttribute(root, ";
  protected final String TEXT_60 = ", ";
  protected final String TEXT_61 = ");" + NL + "\t\t";
  protected final String TEXT_62 = NL + "\t\tXMLUtility.xmlInstance.serializeNode(root, ";
  protected final String TEXT_63 = ", ";
  protected final String TEXT_64 = ");" + NL + "\t\t";
  protected final String TEXT_65 = NL + "\t\t// references" + NL + "\t\t";
  protected final String TEXT_66 = NL + "\t\tXMLUtility.xmlInstance.serializeNodes(root, ";
  protected final String TEXT_67 = ", ";
  protected final String TEXT_68 = ");" + NL + "\t\t";
  protected final String TEXT_69 = NL + "\t\tXMLUtility.xmlInstance.serializeNodesNotContain(root, ";
  protected final String TEXT_70 = ", ";
  protected final String TEXT_71 = ");\t\t" + NL + "\t\t";
  protected final String TEXT_72 = NL + "\t}" + NL + "\t" + NL + "\tpublic void deSerialize(Element root) {" + NL + "\t\tsuper.deSerialize(root);" + NL + "\t\t// attributes" + NL + "\t\t";
  protected final String TEXT_73 = NL + "\t\t";
  protected final String TEXT_74 = " = XMLUtility.xmlInstance.deSerialize";
  protected final String TEXT_75 = "(root, ";
  protected final String TEXT_76 = ");" + NL + "\t\t";
  protected final String TEXT_77 = NL + "\t\t";
  protected final String TEXT_78 = " = (";
  protected final String TEXT_79 = ")XMLUtility.xmlInstance.deSerializeNode(root, ";
  protected final String TEXT_80 = ", this);" + NL + "\t\t";
  protected final String TEXT_81 = NL + "\t\t// references" + NL + "\t\t";
  protected final String TEXT_82 = NL + "\t\tthis.get";
  protected final String TEXT_83 = "().addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ";
  protected final String TEXT_84 = "));" + NL + "\t\t";
  protected final String TEXT_85 = NL + "\t\tthis.get";
  protected final String TEXT_86 = "().addAll(XMLUtility.xmlInstance.deSerializeNodesNotContain(root, ";
  protected final String TEXT_87 = ", this));" + NL + "\t\t";
  protected final String TEXT_88 = NL + "\t}" + NL + "\t" + NL + "\tpublic void dynamicSet(String featureID, Object value) {" + NL + "\t\tif(featureID == null || \"\".equals(featureID)) {" + NL + "\t\t\treturn;" + NL + "\t\t}" + NL + "\t\t// attributes" + NL + "\t\t";
  protected final String TEXT_89 = NL + "\t\telse if(";
  protected final String TEXT_90 = ".equals(featureID)) {" + NL + "\t\t\t";
  protected final String TEXT_91 = " = (";
  protected final String TEXT_92 = ")value;" + NL + "\t\t}" + NL + "\t\t";
  protected final String TEXT_93 = NL + "\t\t// references" + NL + "\t\t";
  protected final String TEXT_94 = NL + "\t\telse if(";
  protected final String TEXT_95 = ".equals(featureID)) {" + NL + "\t\t\tget";
  protected final String TEXT_96 = "().add(value);" + NL + "\t\t}" + NL + "\t\t";
  protected final String TEXT_97 = NL + "\t\telse" + NL + "\t\t\tsuper.dynamicSet(featureID, value);" + NL + "\t}" + NL + "}" + NL + " " + NL + " " + NL + " " + NL + " ";
  protected final String TEXT_98 = NL + " ";

  public String generate(Object argument)
  {
    final StringBuffer stringBuffer = new StringBuffer();
     MetaClass cls = (MetaClass) argument; 
    stringBuffer.append(TEXT_1);
    stringBuffer.append(PackageRetriever.retrievePackage(cls));
    stringBuffer.append(TEXT_2);
    stringBuffer.append(ModelerConstants.pkgBase + "." + ModelerConstants.modelBase + "." + "ModelPackage");
    stringBuffer.append(TEXT_3);
    
	// import dependent classes
	System.out.println("import dependent classes");
	List<String> imports = PackageRetriever.retrieveClassImports(cls);
	for(String tmp : imports) {

    stringBuffer.append(TEXT_4);
    stringBuffer.append(tmp);
    stringBuffer.append(TEXT_5);
    	
	}

    stringBuffer.append(TEXT_6);
    
	System.out.println("gen generalizations");
	// get generalizations
	String firstParentClassName = "MetaModelElement";
	
	if (cls.getGenerals().size() > 0) {
		MetaClass firstParentClass = ((MetaGeneralization)cls.getGenerals().get(0)).getGeneral();
		if(firstParentClass != null)
		{
			firstParentClassName = firstParentClass.getName();	
			if (firstParentClass.getContainer() != cls.getContainer()) {

    stringBuffer.append(TEXT_7);
    stringBuffer.append(PackageRetriever.retrievePackage(firstParentClass));
    stringBuffer.append(TEXT_8);
    stringBuffer.append(firstParentClassName);
    stringBuffer.append(TEXT_9);
    		
			}
		}
	}

    stringBuffer.append(TEXT_10);
    stringBuffer.append(cls.isAbstract()?"abstract ":"");
    stringBuffer.append(TEXT_11);
    stringBuffer.append(cls.getName());
    stringBuffer.append(TEXT_12);
    stringBuffer.append(firstParentClassName);
    stringBuffer.append(TEXT_13);
    stringBuffer.append("I" + cls.getName());
    stringBuffer.append(TEXT_14);
     
		System.out.println("gen attributes");
		List attrs = cls.getAttributes();
		for(int i=0; i<attrs.size(); i++) {
			MetaAttribute attr = (MetaAttribute)attrs.get(i);
			String accessAuthority = "protected";
			if (attr.isDerived()) {
				accessAuthority = "protected";
			}
	
    stringBuffer.append(TEXT_15);
    stringBuffer.append(accessAuthority);
    stringBuffer.append(TEXT_16);
    stringBuffer.append(attr.getType());
    stringBuffer.append(TEXT_17);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_18);
    
	}
	
    stringBuffer.append(TEXT_19);
    
		List<MetaAttribute> derivedAttrs = cls.getDerivedAttributes();
		for (int i = 0; i < derivedAttrs.size(); i++) {
			MetaAttribute attr = derivedAttrs.get(i);
	
    stringBuffer.append(TEXT_20);
    stringBuffer.append(attr.getType());
    stringBuffer.append(TEXT_21);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_22);
    
	}
	
    stringBuffer.append(TEXT_23);
    
		System.out.println("gen references");
	List refs = cls.getReferences();
	for(int i=0; i<refs.size(); i++) {
		MetaReference ref = (MetaReference)refs.get(i);
	
    stringBuffer.append(TEXT_24);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_25);
    
	}
	
    stringBuffer.append(TEXT_26);
    
	List<MetaReference> derivedRefs = cls.getDerivedReferences();
	for(int i=0; i<derivedRefs.size(); i++) {
		MetaReference ref = (MetaReference)derivedRefs.get(i);
	
    stringBuffer.append(TEXT_27);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_28);
    
	}
	
    stringBuffer.append(TEXT_29);
    
	System.out.println("gen getters & setters for attributes");
	List allAttribute = new ArrayList();
	allAttribute.addAll(attrs);
	allAttribute.addAll(derivedAttrs);
	for(int i=0; i<allAttribute.size(); i++) {
	MetaAttribute attr = (MetaAttribute)allAttribute.get(i);
	String attrName = attr.getName();
	attrName = attrName.substring(0,1).toUpperCase()+attrName.substring(1);
	
	String typeName = attr.getType().getName();
	if("String".equals(typeName)
		|| "boolean".equals(typeName)
		|| "int".equals(typeName)
		|| "float".equals(typeName)
		|| "double".equals(typeName)
		|| "char".equals(typeName)) {
	
    stringBuffer.append(TEXT_30);
    stringBuffer.append(cls.getName().toUpperCase());
    stringBuffer.append(TEXT_31);
    stringBuffer.append(attr.getName().toUpperCase());
    stringBuffer.append(TEXT_32);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_33);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_34);
    
	}
	
    stringBuffer.append(TEXT_35);
    stringBuffer.append(typeName);
    stringBuffer.append(TEXT_36);
    stringBuffer.append(attrName);
    stringBuffer.append(TEXT_37);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_38);
    stringBuffer.append(attrName);
    stringBuffer.append(TEXT_39);
    stringBuffer.append(typeName);
    stringBuffer.append(TEXT_40);
    stringBuffer.append(attrName);
    stringBuffer.append(TEXT_41);
    stringBuffer.append(typeName);
    stringBuffer.append(TEXT_42);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_43);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_44);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_45);
    stringBuffer.append(attrName);
    stringBuffer.append(TEXT_46);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_47);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_48);
    stringBuffer.append(attrName);
    stringBuffer.append(TEXT_49);
    
	}
	
    stringBuffer.append(TEXT_50);
    
	List<MetaReference> allRefs = new ArrayList<MetaReference>();
	allRefs.addAll(refs);
	allRefs.addAll(derivedRefs);
	for(int i=0; i<allRefs.size(); i++) {
		MetaReference ref = (MetaReference)allRefs.get(i);
		String refName = ref.getName();
		refName = refName.substring(0,1).toUpperCase()+refName.substring(1);
	
    stringBuffer.append(TEXT_51);
    stringBuffer.append(refName);
    stringBuffer.append(TEXT_52);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_53);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_54);
    stringBuffer.append(ref.getType());
    stringBuffer.append(TEXT_55);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_56);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_57);
    
	}
	
    stringBuffer.append(TEXT_58);
    
		for(int i=0; i<allAttribute.size(); i++) {
			MetaAttribute attr = (MetaAttribute)allAttribute.get(i);
			MetaClassifier type = attr.getType();
			if(type instanceof MetaPrimitiveType) {
		
    stringBuffer.append(TEXT_59);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_60);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_61);
    
			}
			else {
		
    stringBuffer.append(TEXT_62);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_63);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_64);
    
			}
		}
		
    stringBuffer.append(TEXT_65);
    
		for(int i=0; i<allRefs.size(); i++) {
			MetaReference ref = (MetaReference)allRefs.get(i);
			if(ref.isContainment()) {
		
    stringBuffer.append(TEXT_66);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_67);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_68);
    
			}
			else {
		
    stringBuffer.append(TEXT_69);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_70);
    stringBuffer.append(ref.getName());
    stringBuffer.append(TEXT_71);
    
			}
		}
		
    stringBuffer.append(TEXT_72);
    
		for(int i=0; i<allAttribute.size(); i++) {
			MetaAttribute attr = (MetaAttribute)allAttribute.get(i);
			MetaClassifier type = attr.getType();
			if(type instanceof MetaPrimitiveType) {
				String typeName = type.getName();
				// make sure the first letter is uppercased
				typeName = typeName.toUpperCase().charAt(0) 
					+ typeName.toLowerCase().substring(1);
		
    stringBuffer.append(TEXT_73);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_74);
    stringBuffer.append(typeName);
    stringBuffer.append(TEXT_75);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_76);
    	}
			else {
		
    stringBuffer.append(TEXT_77);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_78);
    stringBuffer.append(type.getName());
    stringBuffer.append(TEXT_79);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_80);
    
			}
		}
		
    stringBuffer.append(TEXT_81);
    
		for(int i=0; i<allRefs.size(); i++) {
			MetaReference ref = (MetaReference)allRefs.get(i);
			String refName = ref.getName();
			refName = refName.substring(0,1).toUpperCase()+refName.substring(1);
			if(ref.isContainment()) {
		
    stringBuffer.append(TEXT_82);
    stringBuffer.append(refName);
    stringBuffer.append(TEXT_83);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_84);
    	}
			else {
		
    stringBuffer.append(TEXT_85);
    stringBuffer.append(refName);
    stringBuffer.append(TEXT_86);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_87);
    	}
		}
		
    stringBuffer.append(TEXT_88);
    
		for(int i=0; i<allAttribute.size(); i++) {
			MetaAttribute attr = (MetaAttribute)allAttribute.get(i);
			MetaClassifier type = attr.getType();
			if(type instanceof MetaPrimitiveType) {
				continue;
			}
			else {
		
    stringBuffer.append(TEXT_89);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)attr.getContainer(), attr.getName()));
    stringBuffer.append(TEXT_90);
    stringBuffer.append(attr.getName());
    stringBuffer.append(TEXT_91);
    stringBuffer.append(attr.getType());
    stringBuffer.append(TEXT_92);
    
			}
		}
		
    stringBuffer.append(TEXT_93);
    
		for(int i=0; i<allRefs.size(); i++) {
			MetaReference ref = (MetaReference)allRefs.get(i);
			String refName = ref.getName();
			refName = refName.substring(0,1).toUpperCase()+refName.substring(1);
			if(ref.isContainment()) {
				continue;
			}
			else {
		
    stringBuffer.append(TEXT_94);
    stringBuffer.append(PackageRetriever.retrieveAttributeID((MetaClass)ref.getContainer(), ref.getName()));
    stringBuffer.append(TEXT_95);
    stringBuffer.append(refName);
    stringBuffer.append(TEXT_96);
    
			}
		}
		
    stringBuffer.append(TEXT_97);
    stringBuffer.append(TEXT_98);
    return stringBuffer.toString();
  }
}
